package com.zyg.demo.control;

import android.animation.ValueAnimator;
import android.app.Activity;
import android.graphics.Color;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.chad.library.adapter.base.BaseItemDraggableAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.lzyg.logger.JLog;
import com.zyg.demo.R;
import com.zyg.demo.adapter.PluginAdapter;
import com.zyg.demo.entity.Plugin;
import com.zyg.demo.entity.PluginFolderView;
import com.zyg.demo.listener.DragListener;
import com.zyg.demo.util.Constants;

/**
 * @author zhengyunguang
 * created at 2019-07-17 17:27
 */
public class FolderEditor implements View.OnClickListener, DragListener {


    /**
     * 文件夹动画时长
     */
    private final static long DURATION = 200;

    /**
     * 文件夹标题与文件夹的距离
     */
    private static final int GAP = 30;
    /**
     * 宿主
     */
    private Activity mHost;
    /**
     * 文件夹Plugin
     */
    private Plugin sourcePlugin;

    /**
     * 点击parentRecyclerView中的位置
     */
    private int sourcePos;

    /**
     * decorView
     */
    private ViewGroup decorView;


    /**
     * subRecycler
     */
    private RecyclerView subRecycler;

    /**
     * parentRecycler
     */
    private RecyclerView parentRecycler;

    /**
     * 文件夹标题
     */
    private TextView folderTitle;

    /**
     * subAdapter
     */
    private SubPluginAdapter subAdapter;

    /**
     * parentAdapter
     */
    private PluginAdapter parentAdapter;

    /**
     * 相对于哪个parentRecyclerView中的View展开
     */
    private View anchor;

    /**
     * 用来收缩背景
     */
    private ViewGroup pageContent;

    /**
     * 展开收齐文件夹的动画包装
     */
    private AnimatorPending animPending;

    /**
     * 随文件夹动画的遮罩层
     */
    private FrameLayout coverView;

    /**
     * 处理影子View、传递手势的遮罩层
     */
    private GlueLayout glueLayout;

    private FolderEditor(RecyclerView recyclerView, Plugin sourcePlugin, int position) {
        this.parentRecycler = recyclerView;
        this.mHost = (Activity) recyclerView.getContext();
        this.sourcePlugin = sourcePlugin;
        this.sourcePos = position;
    }

    public static FolderEditor newInstance(RecyclerView recyclerView, Plugin source, int position) {
        return new FolderEditor(recyclerView, source, position);
    }

    /**
     * 展开
     *
     * @param anchor
     */
    public void expand(View anchor) {
        this.anchor = anchor;
        decorView = (ViewGroup) mHost.getWindow().getDecorView();
        pageContent = decorView.findViewById(android.R.id.content);
        coverView = new FrameLayout(mHost);
//        coverView.setBackgroundColor(Color.RED);
        coverView.setBackgroundColor(mHost.getResources().getColor(R.color.trans_gray));
        coverView.setAlpha(0);
        coverView.setOnClickListener(v -> collapse(true));
        coverView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        subRecycler = new RecyclerView(mHost);
        subRecycler.setBackgroundResource(R.drawable.jm_editor_folder_bg);
        subRecycler.setId(R.id.sub_recycler);
        int width = decorView.getWidth() * 2 / 3;
        int height = decorView.getHeight() * 2 / 5;
        FrameLayout.LayoutParams containerParams = new FrameLayout.LayoutParams(width, height);
        coverView.addView(subRecycler, containerParams);
        FrameLayout.LayoutParams labelParams = new FrameLayout.LayoutParams(width, height / 6);
        folderTitle = new TextView(mHost);
        folderTitle.setGravity(Gravity.CENTER);
        coverView.addView(folderTitle, labelParams);
        folderTitle.setText("文件夹");
        folderTitle.setTextSize(18);
        folderTitle.setTextColor(Color.BLACK);

        GridLayoutManager layoutManager = new GridLayoutManager(mHost, 3);
        subRecycler.addItemDecoration(new EditorGridItemDecoration());
        subRecycler.setLayoutManager(layoutManager);
        subAdapter = new SubPluginAdapter();
        subRecycler.setPadding(5, 25, 5, 25);
        subRecycler.setAdapter(subAdapter);
        subAdapter.setNewData(sourcePlugin.plugins);


        /**
         * assembly animatorPending
         */
        int[] position = new int[2];
        anchor.getLocationOnScreen(position);
        animPending = new AnimatorPending();
        animPending.startRecyclerX = position[0];
        animPending.startRecyclerY = position[1];
        float scaleX = (float) anchor.getWidth() / subRecycler.getLayoutParams().width;
        float scaleY = (float) anchor.getHeight() / subRecycler.getLayoutParams().height;
        animPending.startScaleX = scaleX;
        animPending.startScaleY = scaleY;
        animPending.endRecyclerX = (decorView.getWidth() - subRecycler.getLayoutParams().width) / 2;
        animPending.endRecyclerY = (decorView.getHeight() - subRecycler.getLayoutParams().height) / 2;
        startUnfoldAnim();

        glueLayout = new GlueLayout(mHost, parentRecycler, subRecycler);
        glueLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        glueLayout.setDragListener(this);
        glueLayout.addView(coverView);
        decorView.addView(glueLayout);
    }


    /**
     * 添加占位
     */
    private void addPlaceHolder(){
        parentAdapter = (PluginAdapter) parentRecycler.getAdapter();
        Plugin holderPlugin = new Plugin(Constants.TYPE_HOLDER);
        parentAdapter.addData(holderPlugin);
    }

    /**
     * 移除占位
     */
    private void removePlaceHolder(){
        int size = parentAdapter.getItemCount();
        parentAdapter.remove(size - 1);
    }

    private void startUnfoldAnim() {
        subRecycler.setPivotX(0);
        subRecycler.setPivotY(0);
        folderTitle.setPivotX(0);
        folderTitle.setPivotY(0);
        if (animPending != null) {
//            anchor.setVisibility(View.INVISIBLE);
            subRecycler.setX(animPending.startRecyclerX);
            subRecycler.setY(animPending.startRecyclerY);
            subRecycler.setScaleX(animPending.startScaleX);
            subRecycler.setScaleY(animPending.startScaleY);
            subRecycler.animate()
                    .scaleX(animPending.endScaleX)
                    .scaleY(animPending.endScaleY)
                    .translationX(animPending.endRecyclerX)
                    .translationY(animPending.endRecyclerY)
                    .setDuration(DURATION)
                    .setUpdateListener(new SelfAnimator(subRecycler, folderTitle))
                    .start();
            pageContent.animate()
                    .scaleX(0.9f)
                    .scaleY(0.9f)
                    .alpha(0)
                    .setDuration(DURATION)
                    .start();
            coverView.animate()
                    .alpha(1f)
                    .setDuration(DURATION)
                    .start();
            anchor.animate()
                    .alpha(0)
                    .setDuration(DURATION)
                    .withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            addPlaceHolder();
                        }
                    })
                    .start();
        }
    }


    /**
     * 折叠
     */
    public void collapse(final boolean removeAll) {
        if (animPending != null) {
            if(removeAll){
                removePlaceHolder();
            }

            subRecycler.animate()
                    .scaleX(animPending.startScaleX)
                    .scaleY(animPending.startScaleY)
                    .translationX(animPending.startRecyclerX)
                    .translationY(animPending.startRecyclerY)
                    .setDuration(DURATION)
                    .setUpdateListener(new SelfAnimator(subRecycler, folderTitle))
                    .withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            if (removeAll) {
                                decorView.removeView(glueLayout);
                            } else {
                                glueLayout.removeView(coverView);
                            }
                        }
                    })
                    .start();
            pageContent.animate()
                    .scaleX(1)
                    .scaleY(1)
                    .alpha(1)
                    .setDuration(DURATION)
                    .start();
//            coverView.animate()
//                    .alpha(0)
//                    .setDuration(DURATION)
//                    .start();
            anchor.animate()
                    .alpha(1)
                    .setDuration(DURATION + 100)
                    .start();
        }
    }

    @Override
    public void onClick(View v) {
        int viewId = v.getId();
        if (viewId == R.id.folder_name) {
            JLog.d("folder_name onClick");
        }
    }

    @Override
    public void onDragOutOfBounds(int pos, Plugin plugin) {
        collapse(false);
        //同步subRecycler
        Plugin dragPlugin = subAdapter.getItem(pos);
        subAdapter.remove(pos);
        sourcePlugin.removeImageItems(pos);
        //同步parentRecycler
        parentAdapter = (PluginAdapter) parentRecycler.getAdapter();
        if (parentAdapter != null && dragPlugin != null) {
            parentAdapter.notifyItemChanged(sourcePos);
            final int size = parentAdapter.getItemCount();
            final RecyclerView.ViewHolder posHolder = parentRecycler.findViewHolderForAdapterPosition(size - 1);
            if (posHolder == null) {
                return;
            }
            parentAdapter.setData(size - 1, dragPlugin);
            parentAdapter.setCanMove(false);
            subRecycler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    parentAdapter.setCanMove(true);
                }
            }, 800);

            parentRecycler.post(new Runnable() {
                @Override
                public void run() {
                    final RecyclerView.ViewHolder posHolder = parentRecycler.findViewHolderForAdapterPosition(size - 1);
                    if (posHolder == null) {
                        return;
                    }
                    parentAdapter.getItemTouchHelper().startDrag(posHolder);
                    glueLayout.glueTo(posHolder.itemView, true);
                }
            });
        }
    }

    @Override
    public void onDragRelease() {
        decorView.removeView(glueLayout);
    }

    class SubPluginAdapter extends BaseItemDraggableAdapter<Plugin, BaseViewHolder> {

        SubPluginAdapter() {
            super(R.layout.plugin_item_editor, null);
        }

        @Override
        protected void convert(BaseViewHolder helper, Plugin item) {
            helper.setText(R.id.tv_plugin, item.name);
            PluginFolderView folder = helper.getView(R.id.iv_plugin);
            folder.setPlugin(item);
        }
    }

    class SelfAnimator implements ValueAnimator.AnimatorUpdateListener {

        private View anchor;
        private View self;

        private SelfAnimator(View anchor, View self) {
            this.anchor = anchor;
            this.self = self;
        }

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            if (anchor != null && self != null) {
                float anchorTranslationX = anchor.getTranslationX();
                float anchorTranslationY = anchor.getTranslationY();
                float anchorScaleX = anchor.getScaleX();
                float anchorScaleY = anchor.getScaleY();
                self.setTranslationX(anchorTranslationX);
                self.setTranslationY(anchorTranslationY - GAP * anchorScaleY - self.getHeight() * anchorScaleY);
                self.setScaleX(anchorScaleX);
                self.setScaleY(anchorScaleY);
            }
        }
    }

    class AnimatorPending {
        float startScaleX;
        float startScaleY;
        float endScaleX = 1.0f;
        float endScaleY = 1.0f;
        int startRecyclerX;
        int startRecyclerY;
        int endRecyclerX;
        int endRecyclerY;
    }

}
